package modele;

import action.Action;
import controlleur.GestionJeu;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Observable;

/**
 *
 * @author DONG Xiangxiang Durand Rémi
 */
public class Partie extends Observable implements Serializable{

    // utile pour la sérialization
    private long id;
    
    // bergerie
    private Bergerie bergerie;
    
    // liste les moutons sur le plateau
    private List<Mouton> moutons;
    
    // dernier berger à avoir joué
    private Berger dernierBerger;
    private int nombreActionsDernierBerger;
    
    // contient l'historique de la partie
    private Map<Berger, Map<Integer, Action>> listeActionsBerger;
    private boolean estFinie;
    
    
    public Partie(Bergerie bergerie, List<Berger> bergers) {
        this.dernierBerger = bergers.get(0);
        this.nombreActionsDernierBerger = 0;
        this.estFinie = false;
        this.bergerie = bergerie;
        this.id = System.currentTimeMillis();
        
        // créer des moutons pour cette partie
        if(bergers.size()==2)
        {
            Champ champCentral = new Champ();
            champCentral = this.bergerie.getChamps().get(bergerie.getNbRang()-1).get(bergerie.getNbRang()-1);
            int j = 0;
            for(int i=0;i<3;i++)
            {
                for(int k=0;k<bergers.size();k++)
                {
                    List<Champ> champs = new ArrayList<Champ>();
                    champs = champCentral.getPassages().get(j).getChamps();
                    Champ positionMouton = new Champ();
                    if(champs.get(0)!=champCentral) positionMouton = champs.get(0);
                    else positionMouton = champs.get(1);
                    Mouton mouton = new Mouton(positionMouton,bergers.get(k));
                    moutons.add(mouton);
                    j++;
                }
            }
        }
        
        listeActionsBerger = new HashMap<Berger, Map<Integer, Action>>();
        for (int i = 0; i < bergers.size(); i++) {
            listeActionsBerger.put(bergers.get(i), null);
        }
    }
   
    public long getId() {
        return id;
    }
    
    public void setId(long id){
        this.id = id;
    }

    public Map<Berger, Map<Integer, Action>> getCoups() {
        return listeActionsBerger;
    }
    
    /**
     * Permet d'ajouter un tour pour un berger
     * @param berger qui veint de jouer
     * @param action qu'il a joué
     */
    public void ajouterActionBerger(Berger berger, Action action){
        Map<Integer, Action> listeActions;
        
        // si c'est le premier tour
        if(listeActionsBerger.get(berger) == null){
           listeActions = new HashMap<Integer, Action>();
        }
        else{
            // on récupère la liste des tours joués par le berger
            listeActions = listeActionsBerger.get(berger);
        }
        
        // on ajoute le tour
        listeActions.put(listeActions.size(), action);
        // on let à jour la liste des tours du berger
        listeActionsBerger.put(berger, listeActions);

        // si c'est le même berger
        if(this.dernierBerger == berger){
            this.nombreActionsDernierBerger++;
        }
        // si on change de berger
        else{
            this.dernierBerger = berger;
            this.nombreActionsDernierBerger = 0;
        }

        
         // Indiquer que l'objet a changé
        setChanged();
        // Notifier les observateurs
        notifyObservers();
        
        // on vérifie si l'action met fin au jeu
        if(GestionJeu.aGagne(this)){
            this.estFinie = true;
        }
    }

    /**
     * 
     * @return si la partie est finie
     */
    public boolean estFinie() {
        return this.estFinie;
    }

    public Bergerie getBergerie() {
        return bergerie;
    }

    public void setBergerie(Bergerie bergerie) {
        this.bergerie = bergerie;
    }

    public boolean getEstFinie() {
        return estFinie;
    }

    public void setEstFinie(boolean estFinie) {
        this.estFinie = estFinie;
    }

    public Map<Berger, Map<Integer, Action>> getListeToursBerger() {
        return listeActionsBerger;
    }

    public Berger getDernierBerger() {
        return dernierBerger;
    }

    public boolean isEstFinie() {
        return estFinie;
    }

    public int getNombreActionsDernierBerger() {
        return nombreActionsDernierBerger;
    }
    
    public List<Mouton> getMoutons() {
        return moutons;
    }
    
}
